package com.talkyun.openx;

import com.talkyun.openx.server.core.Interceptor;
import com.talkyun.openx.server.core.ServiceFactory;
import com.talkyun.openx.server.impl.SimpleServiceFactory;
import com.talkyun.utils.Reflector;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Restful service scanner
 * <p/>
 * Created by kevin on 3/31 2016.
 */
public class RestfulScanner implements BeanPostProcessor {
    private static final ServiceFactory factory = SimpleServiceFactory.getInstance();
    private static final PathMatcher matcher = new AntPathMatcher();
    private String beanNamePrefix = "/";
    private List<Interceptor> list;
    private String[] paths = {};

    public void setInterceptor(List<Interceptor> interceptor) {
        this.list = interceptor;
    }

    @SuppressWarnings("unchecked")
    public List<Interceptor> getInterceptor() {
        return list == null ? Collections.EMPTY_LIST : list;
    }

    public void setPath(String path) {
        if (path == null || path.trim().length() == 0) {
            return;
        }
        String[] pp = path.trim().split(",|;| ");
        List<String> list = new ArrayList<String>();

        for (String p : pp) {
            if (p == null || p.trim().length() == 0) {
                continue;
            }
            list.add(p.trim());
        }
        this.paths = list.toArray(new String[list.size()]);
    }

    public void setBeanNamePrefix(String prefix) {
        this.beanNamePrefix = prefix;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> api = Reflector.getInterface(bean);
        if (bean instanceof FactoryBean) {
            api = ((FactoryBean) bean).getObjectType();
        }

        if (api != null) {
            // match check
            for (String path : paths) {
                if (matcher.match(path, api.getName())) {
                    // check prefix,resolve dao export problem
                    if (beanNamePrefix != null && beanName != null) {
                        if (!beanName.startsWith(beanNamePrefix)) {
                            continue;
                        }
                    }
                    doExport(bean, api, beanName);
                }
            }
        }
        return bean;
    }

    protected void doExport(Object bean, Class<?> api, String mapping) {
        if (list == null || list.isEmpty()) {
            factory.add(mapping, bean);
        } else {
            factory.add(mapping, list, bean);
        }
    }
}